package fr.esisar.cs420.traitement;
import java.sql.*;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.awt.Desktop;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;

import com.itextpdf.text.BaseColor;
import com.itextpdf.text.Document;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.Element;
import com.itextpdf.text.Font;
import com.itextpdf.text.Paragraph;
import com.itextpdf.text.Phrase;
import com.itextpdf.text.pdf.PdfPCell;
import com.itextpdf.text.pdf.PdfPTable;
import com.itextpdf.text.pdf.PdfWriter;
import java.util.Date;

public class Commande {

	/**
	 * ArrayList<String> permettant de récuperer les commandes 
	 * effectuées par un client
	 */
	public static ArrayList<ParamCommandes> listeCommandes = new ArrayList<ParamCommandes>();

	
	
	/**
	 * Cette méthode permet de retourner la liste de toutes les commandes d'un client.
	 * @param client
	 * @return 
	 * 		List<String>
	 * 
	 */
	public static List<String> afficherCommandes(Client client){		
		List<String> listeCommande = new ArrayList<String>();
		try
		{
			Statement stmt = Application.getStmt();
			String commande = "";
			
			// Passage de la transaction en read only 
			stmt.executeUpdate("SET TRANSACTION READ ONLY");
			
			//Requête pour récuperer certaines informations des commandes d'un client.
			String req = "select idCommande,dateCommande,prixtotal from Commande where idclient like '"+client.getMail()+"'";
			ResultSet rset = stmt.executeQuery(req);
			
			//Insertion de la liste des commandes dans listeCommande
			while (rset.next())
			{
				commande = rset.getString(1)+"                                                        "+rset.getString(2)+"                                                                            "+rset.getString(3);
				listeCommande.add(commande);
				commande = "";
			}
			
			//Fin de la transaction.
			stmt.executeUpdate("COMMIT");
			rset.close();
		} 
		catch (SQLException e)
		{
			e.printStackTrace();
		}
		return listeCommande;
	}
	
	
	
	
	
	/**
	 * Méthode permettant de récuperer la liste des articles
	 * d'une commande.
	 * 
	 * @param idCommande
	 * @return
	 * 		List<String>
	 */
	public static List<String> afficherCommande(int idCommande){
		List<String> listeArticles = new ArrayList<String>();
		Statement stmt = Application.getStmt();
		String article = "";
		try {
			
			// Passage de la transaction en read only 			
			stmt.executeUpdate("SET TRANSACTION READ ONLY");
			
			//requête permettant de récuperer certaines informations d'une commande donnée.
			String req = "select a.idArticle,a.qte,f.libelle,f.prixFormat,al.titre from Article a,Format f,Album al where f.idFormat = a.idFormat AND a.idalbum = al.idalbum AND a.idCommande = "+idCommande;
			ResultSet rset = null;
			rset = stmt.executeQuery(req);
		
			int i = 1;
			//Insertion des articles du client dans listeArticles.
			while (rset.next())
			{
				article = i+"                             "+rset.getString(5)+"                             "+rset.getString(3)+"                             "+rset.getString(4)+"                                           "+rset.getString(2);
				listeArticles.add(article);
				article = "";
				i++;
			}
			
			//Fin de la transaction.
			stmt.executeUpdate("COMMIT");
			rset.close();
			
		} catch (SQLException e) {
			e.printStackTrace();
		}
		
		return listeArticles;
	}
	
	
	
	
	
	/**
	 * Méthode permettant d'enregistrer une commande d'un client.
	 * 
	 * @param client
	 */
	public static void saisieCommande(Client client){
		ResultSet rset;
		Statement stmt = Application.getStmt();

		try
		{
			
				
			
			/**
			 * INSERTION DE LA COMMANDE DANS LA TABLE COMMANDE 
			 */

			String date1=new SimpleDateFormat("dd/MM/yyyy", Locale.FRANCE).format(new Date());
			String heure=new SimpleDateFormat("HH:mm:ss", Locale.FRANCE).format(new Date());
			
			stmt.executeUpdate("SET TRANSACTION ISOLATION LEVEL SERIALIZABLE");
			 
			double prixChaqueCommande = 0;
			 
			//Cacul du prix total de chaque commande du client pour obtenir à la fin le prix de la commande.
			for( int j=0; j < listeCommandes.size(); j++ ){
				prixChaqueCommande += Double.valueOf(listeCommandes.get(j).getPrixFormat()) * listeCommandes.get(j).getQteAlbum();
			}
			 
			//Insertion de la commande dans la table COMMANDE.
			String req = "INSERT INTO COMMANDE VALUES('',to_timestamp('"+date1+" "+heure+"','DD-MM-YYYY HH24:MI:SS'),"+prixChaqueCommande+",";
			req = req + "'"+client.getAdresse()+"',"+client.getCodePostal()+",'"+client.getVille()+"',";
			req = req + "'"+client.getMail()+"')";
	    	stmt.executeUpdate(req);
				
					
	    	/**
	    	 * INSERTION DE LA COMMANDE DANS ARTICLE
	    	 */
	    	
	    	// Passage de la transaction en read only 			
	    	stmt.executeUpdate("SET TRANSACTION READ ONLY");
	    	req = "select IDCOMMANDE from COMMANDE ORDER BY IDCOMMANDE DESC";
	    	rset = stmt.executeQuery(req);
	    	rset.next();
	    	int idCommande  = Integer.valueOf(rset.getString(1));
	    	rset.close();
	    	
	    	//Passage de la transaction en mode SERIALIZABLE.
	    	stmt.executeUpdate("SET TRANSACTION ISOLATION LEVEL SERIALIZABLE");
	    	
	    	//Insertion des articles dans la table Article.
	    	for( int i=0; i < listeCommandes.size(); i++ ){
	    		req = "INSERT INTO ARTICLE VALUES('',"+listeCommandes.get(i).getQteAlbum()+","+idCommande+","+listeCommandes.get(i).getChoixFormat()+","+listeCommandes.get(i).getChoixAlbum()+")" ;
	    		stmt.executeUpdate(req);
	    	}	
			 
	    	//Fin de la transaction. 
	    	stmt.executeUpdate("COMMIT");
	    
	    	//Suppression des commandes du client de la liste.
	    	for(int i=0;i< listeCommandes.size();i++)
	    		listeCommandes.remove(i);
			 	
	    	try {
	    		//Affichage de la facture .pdf.
	    		obtenirFacture(idCommande,stmt);
	    	}
	    	catch (FileNotFoundException e) {
	    		e.printStackTrace();
	    	}	
	    	catch (DocumentException e) {
	    		e.printStackTrace();
	    	}
		
		} 
		catch (SQLException e)
		{
			e.printStackTrace();
		}
	}

	
	
	/**
	 * 
	 * Méthode permettant de génerer une facture format PDF.
	 * 
	 * @param idCommande
	 * @param stmt
	 * @throws DocumentException
	 * @throws FileNotFoundException
	 * @throws SQLException
	 */
	public static void obtenirFacture(int idCommande,Statement stmt) throws DocumentException, FileNotFoundException, SQLException {
		/**
		 * RECUPERATION DE VALEURS POUR LA FACTURE
		 */
		
		stmt.executeUpdate("SET TRANSACTION READ ONLY");
		
		//Requête pour les albums d'un client.
		String req = "select cm.datecommande,cm.prixtotal,cm.adresseexp,cm.codepostalexp,cm.villeexp,cl.nom,cl.prenom from Commande cm,Client cl where cm.idclient = cl.mail AND cm.idcommande = "+idCommande;
		ResultSet rset = stmt.executeQuery(req);
		rset.next();
		String dateCommande = rset.getString(1);
		String prixTotal = rset.getString(2);
		String adresseExp = rset.getString(3);
		String codePostalExp = rset.getString(4);
		String villeExp = rset.getString(5);
		String nomClient = rset.getString(6);
		String prenomClient = rset.getString(7);
		stmt.executeUpdate("COMMIT");
		rset.close();
		
		/**
		 * Insertion des lignes dans la facture
		 */
	  	String FILE = "facture"+idCommande+".pdf";
	  	Font catFont = new Font(Font.FontFamily.TIMES_ROMAN, 18,
	      Font.BOLD);
	  	Font redFont = new Font(Font.FontFamily.TIMES_ROMAN, 12,
	      Font.NORMAL, BaseColor.RED);
	  	Font small= new Font(Font.FontFamily.TIMES_ROMAN, 12,
		      Font.NORMAL);	  
        Document document = new Document();
        PdfWriter.getInstance(document, new FileOutputStream(FILE));
        document.open();
 
        document.addTitle("FACURE");
        document.addSubject("Using iText");
        document.addKeywords("Java, PDF, iText");
	    Paragraph preface = new Paragraph();
	    // We add one empty line
	    addEmptyLine(preface, 1);
	    // Lets write a big header
	    preface.add(new Paragraph("FACTURE DE COMMANDE", catFont));
	
	    addEmptyLine(preface, 1);
	    // Will create: Report generated by: _name, _date
	    preface.add(new Paragraph("PhotoNum ",redFont));
	    addEmptyLine(preface, 3);
	    String date1=new SimpleDateFormat("dd/MM/yyyy", Locale.FRANCE).format(new Date());
	    String heure=new SimpleDateFormat("HH:mm:ss", Locale.FRANCE).format(new Date());
	    preface.add(new Paragraph("Le "+date1+" - "+heure+" à Valence",
	        small));
	
	    addEmptyLine(preface, 2);
	
	    preface.add(new Paragraph("Nom : "+nomClient,
	            small));
	    preface.add(new Paragraph("Prenom : "+prenomClient,
	            small));
	    preface.add(new Paragraph("Adresse : "+adresseExp,
	            small));
	    preface.add(new Paragraph("Code Postal : "+codePostalExp,
	            small));
	    preface.add(new Paragraph("Ville : "+villeExp,
	            small));
	    preface.add(new Paragraph("Date Commande : "+dateCommande,
	            small));	
	    addEmptyLine(preface, 2);
	
	    PdfPTable table = new PdfPTable(6);
	    table.setWidthPercentage((float) 110.3);
	    PdfPCell c1 = new PdfPCell(new Phrase("IdCmde"));
	    c1.setHorizontalAlignment(Element.ALIGN_CENTER);
	    table.addCell(c1);
	
	    c1 = new PdfPCell(new Phrase("IdArticle"));
	    c1.setHorizontalAlignment(Element.ALIGN_CENTER);
	    table.addCell(c1);
	    table.setHeaderRows(1);
	
	    
	    c1 = new PdfPCell(new Phrase("Titre Album/Livre"));
	    c1.setHorizontalAlignment(Element.ALIGN_CENTER);
	    table.addCell(c1);
	
	    c1 = new PdfPCell(new Phrase("Format Impression"));
	    c1.setHorizontalAlignment(Element.ALIGN_CENTER);
	    table.addCell(c1);
	    table.setHeaderRows(1);
	
	    c1 = new PdfPCell(new Phrase("Prix Format"));
	    c1.setHorizontalAlignment(Element.ALIGN_CENTER);
	    table.addCell(c1);
	    table.setHeaderRows(1);
	
	    c1 = new PdfPCell(new Phrase("Quantité"));
	    c1.setHorizontalAlignment(Element.ALIGN_CENTER);
	    table.addCell(c1);
	    table.setHeaderRows(1);

	    
		req = "select a.idArticle,a.qte,f.libelle,f.prixFormat,al.titre from Article a,Format f,Album al where f.idFormat = a.idFormat AND a.idalbum = al.idalbum AND a.idCommande = "+idCommande;
		rset = stmt.executeQuery(req);
		while( rset.next() ){
			String idArticle = rset.getString(1);
			String qte = rset.getString(2);
			String libelle = rset.getString(3);
			String prixFormat = rset.getString(4);
			String titre = rset.getString(5);
			table.addCell(String.valueOf(idCommande));
		    table.addCell(String.valueOf(idArticle));
		    table.addCell(titre);
		    table.addCell(libelle);
		    table.addCell(prixFormat);
		    table.addCell(qte);
		}
		stmt.executeUpdate("COMMIT");
		rset.close();

			
	
	    preface.add(table);
	
	    addEmptyLine(preface, 2);
	
	    PdfPTable table1 = new PdfPTable(2);
	    table1.setWidthPercentage((float) 110.3);
	    PdfPCell c2 = new PdfPCell(new Phrase("Prix Total"));
	    c2.setHorizontalAlignment(Element.ALIGN_LEFT);
	    c2.setBorderColor(BaseColor.RED);
	    table1.addCell(c2);
	
	    c2 = new PdfPCell(new Phrase(prixTotal));
	    c2.setHorizontalAlignment(Element.ALIGN_RIGHT);
	    c2.setBorderColor(BaseColor.RED);
	    table1.addCell(c2);

	
	    preface.add(table1);
	
	    // Now add all this to the document
	    document.add(preface);
	    
	    document.close();    
		Desktop desktop = null; 
		java.net.URI url; 
		try { 
			String chemin = "facture"+idCommande+".pdf";
			url = new java.net.URI(chemin); 
			if (Desktop.isDesktopSupported()) 
			{ 
				desktop = Desktop.getDesktop(); 
				desktop.browse(url); 
			} 
		} 
		catch (Exception ex) { 
		System.out.println(ex.getMessage()); 
		}
  }
	private static void addEmptyLine(Paragraph paragraph, int number) {
		    for (int i = 0; i < number; i++) {
		      paragraph.add(new Paragraph(" "));
		    }	  
	}
	
	/**
	 * Méthode permettant de récuperer la liste 
	 * des formats.
	 * 
	 * @return
	 * 		List<String>
	 * @throws SQLException
	 * 
	 */
	public static List<String> setFormat() throws SQLException{
		List<String> listeFormat = new ArrayList<String>();
		Statement stmt = Application.getStmt();
		
		// Passage de la transaction en read only 			
		stmt.executeUpdate("SET TRANSACTION READ ONLY");
		
		//Requête retournant le libelle de tous les formats.
		String req = "select libelle from format";
		ResultSet rset = stmt.executeQuery(req);
		
		//Insertion du resultat dans la liste listeFormat.
		while (rset.next()){
			listeFormat.add(rset.getString(1));
		}
		
		//Fin de la transaction.
		stmt.executeUpdate("COMMIT");
		rset.close();
		return listeFormat;
	}

	/**
	 * Méthode permettant de récuperer le titre d'un album.
	 * 
	 * @param element
	 * @return
	 * 		titre de l'album
	 * @throws SQLException
	 */
	public static String getTitre(String element) throws SQLException {
		Statement stmt = Application.getStmt();
		
		// Passage de la transaction en read only 			
		stmt.executeUpdate("SET TRANSACTION READ ONLY");
		
		//Requête retournant le titre d'un album donné en argument.
		String req = "select titre from album where idAlbum = "+Album.getElementId(element);
		ResultSet rset = stmt.executeQuery(req);
		rset.next();
		
		String titre = rset.getString(1);
		
		//Fin de la transaction.
		stmt.executeUpdate("COMMIT");
		rset.close();
		return titre;
	}

	/**
	 * Méthode permettant de récuperer le prix d'un format donné.
	 * 
	 * @param text
	 * @return
	 * 		Prix format
	 * @throws SQLException
	 */
	public static String getPrixFormat(String text) throws SQLException {
		Statement stmt = Application.getStmt();
		
		// Passage de la transaction en read only 			
		stmt.executeUpdate("SET TRANSACTION READ ONLY");
		
		//Requête retournant le prix d'un format donné.
		String req = "select prixFormat from format where libelle LIKE '"+text+"'";
		ResultSet rset = stmt.executeQuery(req);
		rset.next();
		String prixFormat = rset.getString(1);
		
		//Fin de la transaction.
		stmt.executeUpdate("COMMIT");
		rset.close();
		return prixFormat;
	}

	/**
	 * Méthode permettant de retourner l'idFormat d'un format donné.
	 * 
	 * @param text
	 * @return
	 * 		IdFormat
	 * @throws SQLException
	 */
	public static int getIdFormat(String text) throws SQLException {
		Statement stmt = Application.getStmt();
		
		// Passage de la transaction en read only 			
		stmt.executeUpdate("SET TRANSACTION READ ONLY");
		
		//Requête retournant l'identifiant d'un format .
		String req = "select idformat from format where libelle LIKE '"+text+"'";
		ResultSet rset = stmt.executeQuery(req);
		rset.next();
		int choixFormat = Integer.valueOf(rset.getString(1));
		
		//Fin de la transaction.
		stmt.executeUpdate("COMMIT");
		rset.close();
		return choixFormat;
	}
}
